package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyZonaDetRequest;
import com.sisgesbyte.dao.beanDao.ProyeccionZonaDetallaRequest;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDetalleDao;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaDetalleEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaEntity;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroProductoZonaBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyZonaDetalleResponse;
import com.sisgesbyte.services.proyeccion.bean.ProyZonaDetalleBean;

@Stateless
public class MantProyeccionZonaDetalleServiceImpl implements
		MantProyeccionZonaDetalleService {

	@EJB
	private MantProyeccionZonaDetalleDao mantProyeccionZonaDetalleDao;
	@EJB
	private MantProyeccionZonaDao mantProyeccionZonaDao;
	@Inject
	private Validaciones validaciones;

	@Override
	public ListaProyZonaDetalleResponse listaProyeccionZonaDetalle(String codTransaccion, FiltroProductoZonaBean filtroBean) {

		String mensajeTransaccionMetodo = "[listaProyeccionZonaDetalle idTx=" + codTransaccion + "] - ";
		ListaProyZonaDetalleResponse response = new ListaProyZonaDetalleResponse();
		
		if (filtroBean.getIdPeriodo() < 1) {
			System.out.println("Seleccionar periodo ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		if (filtroBean.getIdZona() < 1) {
			System.out.println("Seleccionar zona ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		
		List<ProyeccionZonaDetalleEntity> listaProductosZona = null;
		try {
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();

			FiltrosBean listaPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("pz.periodo_id");
			campoPeriodo.add("pz.zona_id");
			listaPeriodo.setCampos(campoPeriodo);
			listaPeriodo.setOperador("=");
			filtro.add(listaPeriodo);
			valores.add(filtroBean.getIdPeriodo());
			valores.add(filtroBean.getIdZona());
			
			// filtro por String
			if (filtroBean.getNombreProducto() != null && filtroBean.getNombreProducto().trim().length() > 0) {
				FiltrosBean listaCampo = new FiltrosBean();
				List<String> campo = new ArrayList<String>();
				campo.add("pzd.id");
				campo.add("m.marca");
				campo.add("p.cod_prod");
				campo.add("p.producto");
				campo.add("cp.nombre");
				listaCampo.setCampos(campo);
				listaCampo.setOperador("like");
				filtro.add(listaCampo);
				valores.add("%" + filtroBean.getNombreProducto() + "%");
			}
			// -------------------
			
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//1.- consultamos la lista de productos de cada zona
			listaProductosZona = mantProyeccionZonaDetalleDao.listaProyeccionZonaDetalle(filtroSQL);
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		List<ProyZonaDetalleBean> listaProyeccionZonaDetalle = new ArrayList<ProyZonaDetalleBean>();
		
		for(ProyeccionZonaDetalleEntity ls :listaProductosZona){
			ProyZonaDetalleBean bean = new ProyZonaDetalleBean();
			bean.setCantidadProyectada(ls.getCantidad_proyectada());
			bean.setCategoriaProducto(validaciones.validarCamposString(ls.getCategoria_producto()));
			bean.setCategoriaProductoId(ls.getCategoria_producto_id());
			bean.setCodigoBanda(validaciones.validarCamposString(ls.getCodigo_banda()));
			bean.setCodProd(validaciones.validarCamposString(ls.getCod_prod()));
			bean.setId(ls.getId());
			bean.setMarca(validaciones.validarCamposString(ls.getMarca()));
			bean.setMarcaId(ls.getMarca_id());
			bean.setPeriodoId(ls.getPeriodo_id());
			bean.setPrecioPromedio(ls.getPrecio_promedio());
			bean.setProducto(validaciones.validarCamposString(ls.getProducto()));
			bean.setProductoId(ls.getProducto_id());
			bean.setProyeccionZonaId(ls.getProyeccion_zona_id());
			bean.setZonaId(ls.getZona_id());
			
			listaProyeccionZonaDetalle.add(bean);
		}
		
		if(listaProyeccionZonaDetalle.size() > 0){
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionZonaDetalle(listaProyeccionZonaDetalle);
		} else {
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}
		
		return response;
	}

	@Override
	public GenericResponse nuevaProyeccionZonaDetalle(String codTransaccion,
			ProyZonaDetalleBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccionZonaDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		if (request.getPeriodoId() < 1) {
			System.out.println("Seleccionar periodo ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		if (request.getZonaId() < 1) {
			System.out.println("Seleccionar zona ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		List<ProyeccionZonaEntity> listaProyZonas=null;
		try{
			//1.- obtenemos la lista de proyeccion por zona
			listaProyZonas = listaProyeccionZona(request.getPeriodoId(), request.getZonaId());
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyeccion de zonas de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		//2.- verificamos si existe la proyeccion de la zona
		boolean existe = false;
		int idProyeccionZona = 0;
		for(ProyeccionZonaEntity ls : listaProyZonas){
			if(ls.getPeriodo_id() == request.getPeriodoId() && ls.getZona_id()==request.getZonaId()){
				existe=true;
				idProyeccionZona = ls.getId();
				break;
			}
		}
		if(!existe){
				//3.- si no existe insertamos la proyeccion de la zona
				ProyeccionZonaDetallaRequest req = new ProyeccionZonaDetallaRequest();
				req.setIdPeriodo(request.getPeriodoId());
				req.setIdZona(request.getZonaId());
				req.setCodigoBanda("");
				req.setMontoProyectado(BigDecimal.ZERO);
				try{
				GenericEntity nuevoProyZona = mantProyeccionZonaDao.guardarProyeccionZona(req);
				
				if(nuevoProyZona.getCod_error()==Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
					System.out.println("Se registro correctamente ");
					
					//capturamos el id del registro
					List<ProyeccionZonaEntity> zonaResponse = listaProyeccionZona(request.getPeriodoId(), request.getZonaId());
					
					for(ProyeccionZonaEntity listaZona : zonaResponse){
						if(request.getPeriodoId()==listaZona.getPeriodo_id() && request.getZonaId()==listaZona.getZona_id()){
							idProyeccionZona =listaZona.getId();
							break;
						}
					}
				}else{
					System.out.println("Un error al registrar ");
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					return response;
				}
			}catch(Exception e){
				System.out.println("Error al registrar la proyeccion de la Zona " + e.getMessage());
				response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
				response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
				return response;
			}
		}
		GenericEntity responseDao = null;
		try{
			ProyZonaDetRequest req = new ProyZonaDetRequest();
			req.setProyeccionZonaId(idProyeccionZona);
			req.setProductoId(request.getProductoId());
			req.setCodigoBanda(request.getCodigoBanda());
			req.setCantidadProyectada(request.getCantidadProyectada());
			
			responseDao = mantProyeccionZonaDetalleDao.guardarProyeccionZonaDetalle(req);
			
			if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
				
				
				ProyZonaDetalleBean reqZona = new ProyZonaDetalleBean();
				reqZona.setPeriodoId(request.getPeriodoId());
				reqZona.setZonaId(request.getZonaId());
				reqZona.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
				//actualizamos el monto de la proyeccion de la zona
				GenericResponse actualizar = actualizarMontoProyeccionZona(codTransaccion, reqZona);
				
				if(actualizar.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(actualizar.getCodigoRespuesta());
					response.setMensajeRespuesta(actualizar.getMensajeRespuesta());
				}
				
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
	
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse editarProyeccionZonaDetalle(String codTransaccion,
			ProyZonaDetalleBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionZonaDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try{
			ProyZonaDetRequest req = new ProyZonaDetRequest();
			req.setId(request.getId());
			req.setProyeccionZonaId(request.getProyeccionZonaId());
			req.setProductoId(request.getProductoId());
			req.setCodigoBanda(request.getCodigoBanda());
			req.setCantidadProyectada(request.getCantidadProyectada());
			
			responseDao = mantProyeccionZonaDetalleDao.actualizarProyeccionZonaDetalle(req);
			
			if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
				
				ProyZonaDetalleBean reqZona = new ProyZonaDetalleBean();
				reqZona.setPeriodoId(request.getPeriodoId());
				reqZona.setZonaId(request.getZonaId());
				reqZona.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
				//actualizamos el monto de la proyeccion de la zona
				GenericResponse actualizar = actualizarMontoProyeccionZona(codTransaccion, reqZona);
				
				if(actualizar.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(actualizar.getCodigoRespuesta());
					response.setMensajeRespuesta(actualizar.getMensajeRespuesta());
				}
			} else {
				response.setCodigoRespuesta(codTransaccion);
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
	
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionZonaDetalle(String codTransaccion,
			ProyZonaDetalleBean request) {
		String mensajeTransaccionMetodo = "[deleteProyeccionZonaDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try{
			responseDao = mantProyeccionZonaDetalleDao.eliminarProyeccionZonaDetalle(request.getId());
			if (responseDao.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)) {
				
				ProyZonaDetalleBean reqZona = new ProyZonaDetalleBean();
				reqZona.setPeriodoId(request.getPeriodoId());
				reqZona.setZonaId(request.getZonaId());
				reqZona.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
				//actualizamos el monto de la proyeccion de la zona
				GenericResponse actualizar = actualizarMontoProyeccionZona(codTransaccion, reqZona);
				
				if(actualizar.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(actualizar.getCodigoRespuesta());
					response.setMensajeRespuesta(actualizar.getMensajeRespuesta());
				}
			} else {
				response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
				response.setMensajeRespuesta(responseDao.getMsj_error());
			}
		} catch (Exception e) {
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al eliminar  en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_EDITAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_EDITAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
	}
	
	public List<ProyeccionZonaEntity> listaProyeccionZona(int idPeriodo, int idZona){
		
		List<ProyeccionZonaEntity> listaProyZonas = null;
		
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();

			FiltrosBean listaPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("pz.periodo_id");
			campoPeriodo.add("pz.zona_id");
			listaPeriodo.setCampos(campoPeriodo);
			listaPeriodo.setOperador("=");
			filtro.add(listaPeriodo);
			valores.add(idPeriodo);
			valores.add(idZona);
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//1.- obtenemos la lista de proyeccion de la zona por periodo
			listaProyZonas = mantProyeccionZonaDao.listaProyeccionZona(filtroSQL);
		}catch(Exception e){
			System.out.println("Error al listar las proyecciones de zona " + e);
		}
		
		return listaProyZonas;
	}

	@Override
	public GenericResponse actualizarMontoProyeccionZona(String codTransaccion, ProyZonaDetalleBean request) {
		String mensajeTransaccionMetodo = "[actualizarMontoProyeccionZona idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			FiltroProductoZonaBean filtroBean = new FiltroProductoZonaBean();
			filtroBean.setIdPeriodo(request.getPeriodoId());
			filtroBean.setIdZona(request.getZonaId());
			filtroBean.setNombreProducto("");
			//1.- obtenemos la lista de detalle de proyeccion por zona y periodo
			ListaProyZonaDetalleResponse responseDao = listaProyeccionZonaDetalle(codTransaccion, filtroBean);
			if(responseDao.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				
				BigDecimal montoTotal = BigDecimal.ZERO;
				for(ProyZonaDetalleBean ls : responseDao.getListaProyeccionZonaDetalle()){
					if(filtroBean.getIdPeriodo()==ls.getPeriodoId() && filtroBean.getIdZona()==ls.getZonaId()){
						montoTotal = montoTotal.add(ls.getCantidadProyectada().multiply(ls.getPrecioPromedio()));
					}
				}
				
				List<ProyeccionZonaEntity> listaProyZonas=null;
				try{
					//2.- obtenemos el id de la proyeccion de la zona
					listaProyZonas = listaProyeccionZona(request.getPeriodoId(), request.getZonaId());
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyeccion de zonas de  BD " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				int idProyZona = 0;
				for(ProyeccionZonaEntity proyZona :listaProyZonas){
					idProyZona = proyZona.getId();
				}
				
				//3.- actualizamos el monto de la proyeccion de la zona
				ProyeccionZonaDetallaRequest reqZona = new ProyeccionZonaDetallaRequest();
				reqZona.setId(idProyZona);
				reqZona.setIdPeriodo(request.getPeriodoId());
				reqZona.setIdZona(request.getZonaId());
				reqZona.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
				reqZona.setMontoProyectado(montoTotal);
				
				GenericEntity actualizarProy = mantProyeccionZonaDao.actualizarProyeccionZona(reqZona);
				
				if(actualizarProy.getCod_error()==Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
				}else{
					response.setCodigoRespuesta(codTransaccion);
					response.setCodigoRespuesta(String.valueOf(responseDao.getCodigoRespuesta()));
					response.setMensajeRespuesta(responseDao.getMensajeRespuesta());
				}
			
			}else{
				response.setCodigoRespuesta(codTransaccion);
				response.setCodigoRespuesta(String.valueOf(responseDao.getCodigoRespuesta()));
				response.setMensajeRespuesta(responseDao.getMensajeRespuesta());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyeccion de detalle de la zonas de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		return response;
	}
}